package com.demandbreakdown.xiyun.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.demandbreakdown.xiyun.common.annotation.ApiLog;
import com.demandbreakdown.xiyun.common.base.Result;
import com.demandbreakdown.xiyun.common.base.ResultUtils;
import com.demandbreakdown.xiyun.model.dto.space.*;
import com.demandbreakdown.xiyun.model.vo.space.MySpaceVO;
import com.demandbreakdown.xiyun.model.vo.space.SpaceInviteVO;
import com.demandbreakdown.xiyun.model.vo.space.SpaceUserListVO;
import com.demandbreakdown.xiyun.model.vo.space.SpaceVO;
import com.demandbreakdown.xiyun.service.SpaceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

/**
 * 空间管理控制器
 *
 * @author poxz
 */
@RestController
@RequestMapping("/space")
@RequiredArgsConstructor
@Tag(name = "空间管理", description = "空间创建、管理、成员管理相关接口")
public class SpaceController {

    private final SpaceService spaceService;

    /**
     * 创建空间
     */
    @ApiLog("创建空间")
    @Operation(summary = "创建空间", description = "创建私有或团队空间，owner自动加入")
    @PostMapping
    @SaCheckLogin
    public Result<SpaceVO> createSpace(@Valid @RequestBody SpaceCreateDTO spaceCreateDTO) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceVO spaceVO = spaceService.createSpace(userId, spaceCreateDTO);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 我创建/加入的空间列表
     */
    @ApiLog("我的空间列表")
    @Operation(summary = "我的空间列表", description = "获取用户创建和加入的空间列表")
    @GetMapping("/my")
    @SaCheckLogin
    public Result<MySpaceVO> getMySpaces() {
        Long userId = StpUtil.getLoginIdAsLong();
        MySpaceVO mySpaceVO = spaceService.getMySpaces(userId);
        return ResultUtils.success(mySpaceVO);
    }

    /**
     * 空间详情
     */
    @ApiLog("空间详情")
    @Operation(summary = "空间详情", description = "获取空间详细信息和使用统计")
    @GetMapping("/{id}")
    @SaCheckLogin
    public Result<SpaceVO> getSpaceById(@Parameter(description = "空间ID", required = true) @PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceVO spaceVO = spaceService.getSpaceById(id, userId);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 更新空间信息
     */
    @ApiLog("更新空间信息")
    @Operation(summary = "更新空间信息", description = "只有空间Owner可以修改空间信息")
    @PutMapping("/{id}")
    @SaCheckLogin
    public Result<SpaceVO> updateSpace(
            @Parameter(description = "空间ID", required = true) @PathVariable Long id,
            @Valid @RequestBody SpaceUpdateDTO spaceUpdateDTO) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceVO spaceVO = spaceService.updateSpace(id, userId, spaceUpdateDTO);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 升级空间等级
     */
    @ApiLog("升级空间等级")
    @Operation(summary = "升级空间等级", description = "升级空间到高级版或至尊版")
    @PostMapping("/{id}/upgrade")
    @SaCheckLogin
    public Result<SpaceVO> upgradeSpace(
            @Parameter(description = "空间ID", required = true) @PathVariable Long id,
            @Valid @RequestBody SpaceUpgradeDTO spaceUpgradeDTO) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceVO spaceVO = spaceService.upgradeSpace(id, userId, spaceUpgradeDTO);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 生成邀请码（团队空间）
     */
    @ApiLog("生成邀请码")
    @Operation(summary = "生成邀请码", description = "为团队空间生成邀请码，Owner和Editor可使用")
    @PostMapping("/{id}/invite")
    @SaCheckLogin
    public Result<SpaceInviteVO> generateInviteCode(@Parameter(description = "空间ID", required = true) @PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceInviteVO spaceInviteVO = spaceService.generateInviteCode(id, userId);
        return ResultUtils.success(spaceInviteVO);
    }

    /**
     * 通过邀请码加入空间
     */
    @ApiLog("加入空间")
    @Operation(summary = "加入空间", description = "通过邀请码加入团队空间")
    @PostMapping("/join")
    @SaCheckLogin
    public Result<SpaceVO> joinSpace(@Valid @RequestBody SpaceJoinDTO spaceJoinDTO) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceVO spaceVO = spaceService.joinSpace(userId, spaceJoinDTO);
        return ResultUtils.success(spaceVO);
    }

    /**
     * 空间成员列表
     */
    @ApiLog("空间成员列表")
    @Operation(summary = "空间成员列表", description = "获取空间所有成员信息")
    @GetMapping("/{id}/member")
    @SaCheckLogin
    public Result<SpaceUserListVO> getSpaceMembers(@Parameter(description = "空间ID", required = true) @PathVariable Long id) {
        Long userId = StpUtil.getLoginIdAsLong();
        SpaceUserListVO spaceUserListVO = spaceService.getSpaceMembers(id, userId);
        return ResultUtils.success(spaceUserListVO);
    }

    /**
     * 修改成员角色
     */
    @ApiLog("修改成员角色")
    @Operation(summary = "修改成员角色", description = "只有空间Owner可以修改成员角色")
    @PatchMapping("/{id}/member/{userId}/role")
    @SaCheckLogin
    public Result<Void> updateMemberRole(
            @Parameter(description = "空间ID", required = true) @PathVariable Long id,
            @Parameter(description = "成员用户ID", required = true) @PathVariable Long userId,
            @Valid @RequestBody SpaceUserRoleUpdateDTO roleUpdateDTO) {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        spaceService.updateMemberRole(id, currentUserId, userId, roleUpdateDTO);
        return ResultUtils.success();
    }

    /**
     * 踢出成员
     */
    @ApiLog("踢出成员")
    @Operation(summary = "踢出成员", description = "只有空间Owner可以踢出成员，不能踢自己")
    @DeleteMapping("/{id}/member/{userId}")
    @SaCheckLogin
    public Result<Void> removeMember(
            @Parameter(description = "空间ID", required = true) @PathVariable Long id,
            @Parameter(description = "成员用户ID", required = true) @PathVariable Long userId) {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        spaceService.removeMember(id, currentUserId, userId);
        return ResultUtils.success();
    }

    /**
     * 转让空间
     */
    @ApiLog("转让空间")
    @Operation(summary = "转让空间", description = "转让空间所有权，原Owner变为Editor，新Owner变为Owner")
    @PutMapping("/{id}/transfer")
    @SaCheckLogin
    public Result<Void> transferSpace(
            @Parameter(description = "空间ID", required = true) @PathVariable Long id,
            @Valid @RequestBody SpaceTransferDTO spaceTransferDTO) {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        spaceService.transferSpace(id, currentUserId, spaceTransferDTO);
        return ResultUtils.success();
    }

    /**
     * 删除空间
     */
    @ApiLog("删除空间")
    @Operation(summary = "删除空间", description = "删除空间及其所有相关数据（仅Owner可操作）")
    @DeleteMapping("/{id}")
    @SaCheckLogin
    public Result<Void> deleteSpace(
            @Parameter(description = "空间ID", required = true) @PathVariable Long id) {
        Long currentUserId = StpUtil.getLoginIdAsLong();
        spaceService.deleteSpace(id, currentUserId);
        return ResultUtils.success();
    }
}
